﻿using System.Collections.Generic;
using CarlosAg.ExcelXmlWriter;
using SdmxMl.Common;
using SdmxMl.Manager;
using SdmxMl.Structure;

namespace SdmxMl.Excel
{
    /// <summary>
    /// Specialized class for generating Excel export of MSD 
    /// </summary>
    public class ExcelExportMSD : ExcelExportBase
    {
        #region Internal Members

        private SmManager smManager;
        private MetadataStructureDefinitionType msd;
        private int itemCount;

        #endregion

        #region C'tor

        /// <summary>C'tor with specified artefact to transform</summary>
        /// <param name="m">the MSD insrtance</param>
        public ExcelExportMSD(MetadataStructureDefinitionType m, SmManager sm)
        {
            msd = m;
            smManager = sm;
        }
        #endregion

        #region Header

        /// <summary>
        /// Generate Header row names for a report page
        /// </summary>
        private void GenerateHeaderNames(ReportStructureType report)
        {
            headerColitems = new List<string>(16);

            headerColitems.Add("ConceptScheme");
            headerColitems.Add("Concept");
            headerColitems.Add("Parent");
            headerColitems.Add("Level");

            foreach (string lg in SdmxMl.Common.LangSupport.SupportedLanguages)
                headerColitems.Add("Name_" + lg);

            foreach (string lg in SdmxMl.Common.LangSupport.SupportedLanguages)
                headerColitems.Add("Desc_" + lg);

            foreach (string lg in SdmxMl.Common.LangSupport.SupportedLanguages)
                headerColitems.Add("Context_" + lg);

            headerColitems.Add("Text Format");
            headerColitems.Add("Usage");

            anInventory = new AnnotationInventory();

            
            foreach (MetadataAttributeType it in report.MetadataAttributeList)
                FillAnnot(it);

            anInventory.GenerateAnnotationHeader(headerColitems);
        }
        #endregion

        #region Overriden Export Method

        public override void Export()
        {
            // Ensure in manager
            smManager.PutArtefact(SdmxArtefactType.HierarchicalCodelists, msd);
            ArtefactRefTypedList artl = msd.ArtefactRefList;
            smManager.LoadMissingArtefactsFromReferenceMgr(artl);
            smManager.LoadMissingArtefactsFromRegistry(artl);


            GenerateBook("SMS", "OFS");
            GenerateWorksheetArtefact(msd);

            foreach (ReportStructureType report in msd.ReportStructureList)
            {
                GenerateHeaderNames(report);
                sheet = GenerateWorksheetHeader(
                    headerColitems.ToArray(), "Report " + report.Id, msd.ReportStructureList.Count);

                itemCount = 0;
                CreateRows(report.MetadataAttributeList);

                // Update sheet count
                sheet.Table.ExpandedRowCount = 1 + itemCount;
            }

        }


        public void CreateRows(MetadataAttributeTypeList mdaList)
        {
            itemCount += mdaList.Count;
            foreach (MetadataAttributeType mda in mdaList)
                FillRow(null, mda, 0);
        }

        protected void FillAnnot(MetadataAttributeType item)
        {
            anInventory.Inventory(item.AnnotationList, false);
            foreach (MetadataAttributeType it in item.MetadataAttributeList)
                FillAnnot(it);
        }


        protected void FillRow(MetadataAttributeType parent, MetadataAttributeType item, int level)
        {
            WorksheetRow row = sheet.Table.Rows.Add();
            AddCell(row, item.ConceptSchemeInfo.FullIdent);
            AddCell(row, item.ConceptInfo.Id);
            AddCell(row, parent != null ? parent.ConceptInfo.Id : string.Empty);
            AddCell(row, (level + 1).ToString());

            ArtefactRefTyped art = new ArtefactRefTyped(SdmxArtefactType.Concepts, item.ConceptSchemeInfo.FullIdent);
            ConceptSchemeType cst = smManager.GetArtefact(art) as ConceptSchemeType;
            ConceptType c = cst.ConceptList.LocateItem(item.ConceptInfo.Id) as ConceptType;

            foreach (string lg in SdmxMl.Common.LangSupport.SupportedLanguages)
                AddCell(row, c.Name.GetIfDefinedForLanguage(lg));

            MultiLang desc = c.Description;
            if (desc != null && desc.IsEmpty == false)
            {
                foreach (string lg in SdmxMl.Common.LangSupport.SupportedLanguages)
                    AddCell(row, desc.GetIfDefinedForLanguage(lg));
            }
            else
            {
                foreach (string lg in SdmxMl.Common.LangSupport.SupportedLanguages)
                    AddCell(row, string.Empty);
            }

            desc = c.AnnotationList.GetInternationalizedTextOfAnnotationType("CONTEXT");
            if (desc != null && desc.IsEmpty == false)
            {
                foreach (string lg in SdmxMl.Common.LangSupport.SupportedLanguages)
                    AddCell(row, desc.GetIfDefinedForLanguage(lg));
            }
            else
            {
                foreach (string lg in SdmxMl.Common.LangSupport.SupportedLanguages)
                    AddCell(row, string.Empty);
            }

            AddCell(row, item.TextFormat.TextType.ToString());
            AddCell(row, item.UsageStatus.ToString());

            // All annotations
            AddAnnotations(row, item.AnnotationList);

            // Recurse
            itemCount += item.MetadataAttributeList.Count;
            foreach (MetadataAttributeType it in item.MetadataAttributeList)
                FillRow(item, it, level + 1);
        }
        #endregion

    }
}

